package com.n9.component.table;


import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.util.*;

/**
 * 注解方式的tableModel基类
 * @author ice
 */
public abstract class AnnotationTableModel<E> extends AbstractTableModel {
    protected List<E> rows = new ArrayList<>(0);

    private JTableHelper tableHelper;

    public AnnotationTableModel(Class<E> clazz, JTable jtable) {
        init(clazz, jtable);
    }

    private void init(Class<E> clazz, JTable jtable) {
        tableHelper = new JTableHelper(clazz);
        jtable.setModel(this);

        TableColumnModel columnModel = jtable.getColumnModel();
        for (int i = 0; i < jtable.getColumnCount(); i++) {
            TableColumn column = columnModel.getColumn(i);
            column.setPreferredWidth(tableHelper.getPreferredWidth(i));

            final int minWidth = tableHelper.getMinWidth(i);
            final int maxWidth = tableHelper.getMaxWidth(i);
            if (minWidth >= 0) {
                column.setMinWidth(minWidth);
            }
            if (maxWidth >= 0) {
                column.setMaxWidth(maxWidth);
            }
        }
    }

    public JTableHelper getTableHelper() {
        return tableHelper;
    }

    public void setRows(List<E> rows) {
        this.rows = rows;
        this.fireTableDataChanged();
    }

    public void clearRows() {
        this.rows.clear();
        this.fireTableDataChanged();
    }

    public void addRow(E e) {
        this.rows.add(e);
        this.fireTableDataChanged();
    }

    /**
     * 根据过滤器条件删除行
     * @param filter
     * @param fireTableDateChanged
     */
    public void delete(RowFilter<E> filter, boolean fireTableDateChanged) {
        boolean hasChanged = false;
        Iterator<E> it = rows.iterator();
        while(it.hasNext()) {
            E e = it.next();
            if (Objects.isNull(e)) {
                continue;
            }
            if (filter.accept(e)) {
                hasChanged = true;
                it.remove();
            }
        }
        if (hasChanged && fireTableDateChanged) {
            this.fireTableDataChanged();
        }
    }


    public void addRows(List<E> rows) {
        this.rows.addAll(rows);
        this.fireTableDataChanged();
    }

    public void deleteRow(int selectedRow) {
        this.rows.remove(selectedRow);
        this.fireTableRowsDeleted(selectedRow, selectedRow);
    }

    public E getTableRow(int rowIndex) {
        return this.rows.get(rowIndex);
    }

    @Override
    public int getRowCount() {
        return rows.size();
    }

    @Override
    public int getColumnCount() {
        return tableHelper.getColumnCount();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Object rowData = rows.get(rowIndex);
        return tableHelper.getColumnValue(rowData,rowIndex, columnIndex);
    }

    /**
     * 更新行数据
     * @param e
     */
    public abstract void updateRow(E e);

    @Override
    public String getColumnName(int column) {
        return tableHelper.getColumnName(column);
    }

    public List<E> getRows() {
        return Collections.unmodifiableList(this.rows);
    }

}
